查看原文
其他

Google DeepMind科学家 Nicholas Carlini 如何使用 AI(2)- 具体实例

renee创业狗 Renee 创业随笔
2024-10-10

To build complete applications for me

去年,Nicholas 制作了一个测验,让人们测试自己预测 GPT-4 解决一些任务能力的水平。这个测验非常受欢迎,浏览量超过了一千万次。几乎整个初始版本的这个应用程序都是由 GPT-4 编写的。他通过一系列问题逐步完成了这个应用程序的构建,从询问应用程序的基本结构开始,慢慢添加各种功能。整个对话总共达到了3万字,充分展示了当时最先进的 GPT-4 模型的能力。

有时 Nicholas 只是用文字描述他想要的内容,并要求模型提供完整的实现方案;有时他会请求一个特定的更改(例如,“能不能不说这和平均分的对比,而是使用 KDE 说出这是在哪个百分位?”);有时他会提出一些完全没有明确说明的问题,比如直接粘贴错误信息(例如,“绘图:numpy.linalg.LinAlgError: singular matrix”);有时他则会询问一些简单的、一时性的问题(例如,“如何使用 JavaScript 向页面添加一个 iframe,内容从字符串中加载?”)。

总的来说,这种方法之所以有效,是因为语言模型非常擅长解决人们以前已经解决过的问题,而这个测验的 99% 只是一些基本的 HTML 和一个 Python 的网页服务器后端,其他任何人都可以编写。这个测验之所以有趣并受到欢迎,不是因为其背后的技术,而是因为测验的内容。因此,自动化处理所有无聊的部分让 Nicholas 很容易完成这个测验。LLM 让绝大多数人仅通过寻求解决方案来解决他们以前从未解决过的有意义的任务。

Nicholas 还有一些类似的例子,都是通过模型为他编写整个应用程序的,当这些应用程序上线时,他会明确指出它们是在语言模型的帮助下完成的。

As a tutor for new technologies

对于 Nicholas 来说,大多数新框架/工具如 Docker、Flexbox 或 React 可能是新的,但对于其他人来说并不新鲜。世界上可能有数万甚至数十万人已经彻底掌握了这些工具,因此当前的语言模型也是如此。因此不再需要通过阅读一些假设读者已经具备特定知识并希望实现特定目标的静态教程来入门,而是可以与语言模型进行互动,学习解决任务所需的知识。

例如,今年早些时候,Nicholas 构建了一个大型语言模型(LLM)评估框架,他希望能够在一个受限的环境中运行由 LLM 生成的代码,以避免误删电脑上的随机文件等问题。Docker 是实现这一任务的完美工具,但 Nicholas 以前从未使用过它。

重要的是,这个项目的目标并不是使用 Docker,Docker 只是 Nicholas 为实现目标所需的工具。Nicholas 只想了解 Docker 的 10% 功能,以确保自己在最基本的情况下安全地使用它。

如果是在 90 年代,Nicholas 基本上得买一本关于如何从原理上使用 Docker 的书,读完前几章,然后尝试跳着阅读,找出如何实现他想要的功能。在那之后情况有所改善;如果是在上一个十年,Nicholas 会在网上搜索一些描述如何使用 Docker 的教程,尝试跟着做,然后搜索出现的错误信息,看看是否有人遇到过同样的问题。

To get started with new projects

最近 Nicholas 想尝试写一些 CUDA 代码,以对比 GPU 上的一个简单贪心搜索与某人的高效优化的 CPU 实现的性能。Nicholas 选择了让语言模型教他如何实现他想要的功能。Nicholas 以前使用过微控制器,所以他大致了解它们的工作原理,但他从未使用过 Pico W。他所需要的只是一些帮助,让他能够搞定所有的依赖项,剩下的他可以自己解决。

对于新的微控制器,Nicholas 总是先写一个“Hello World”程序,也就是让 LED 闪烁。通过这个程序,他可以测试自己是否能够编译并上传代码到设备,所有引脚是否设置正确,并基本上确认自己知道在做什么。所以,他直接请求一个 LED 闪烁程序。(再次强调:这个程序在网上存在吗?几乎可以肯定。但他还得去搜索。)一旦这个代码运行起来,从这里开始,Nicholas 就知道该怎么做了。他知道 Python 是怎么工作的(信不信由你!)。所以他可以直接从这里开始编辑代码,因为已经把 MicroPython 的特殊部分搞定了。

当 Nicholas 遇到需要特别处理的问题时,他可以继续请求模型帮助他解决。比如,这里他继续让模型帮他写一个连接 WiFi 的脚本。

当他再次卡住,需要连接到 MQTT 服务器时,他再次请求模型帮助他解决问题。

现在,Nicholas 不断地这样做。即使是本段开头的例子也不是假设的——这是他请求如何使用 Flexbox 的真实经历,因为他上次学习 HTML 布局的新方法时,还是用 div 来替代表格。

To simplify code

作为一名安全研究员,Nicholas 经常遇到这样的情况:他需要面对一个包含几千行代码的别人研究项目的新仓库,并且必须弄清楚它的工作原理,然后再对其进行攻击。乍一听,这似乎并不难,如果每个人都写干净的代码,这确实不应该是个难题,但现实并非如此。研究人员没有动机发布干净的代码,因此人们通常会发布他们手头上能用的任何代码,无论它多么混乱。(Nicholas 也会这么做。)

Nicholas 没有任何可以在这里分享的与研究相关的例子,但他可以分享一个自己正在进行的个人项目的例子。有人说他对康威的生命游戏有一种不健康的痴迷。最近,Nicholas 想找到一种从 Python 快速评估一些生命游戏模式的方法。有一个叫做 golly 的 C++ 工具非常适合这个需求,但他不想将自己的 Python 代码重写成 C++。

golly 有一个可以满足他需求的 CLI 工具——他只需要找到一种正确调用它的方法。第一步是处理支持大约 50 种不同命令行选项的 C++ 代码,并让它只做他想要的那一件事。所以,Nicholas 把所有 500 行的 C++ 代码都输入到了 LLM 中,并要求生成一个更短的文件来实现相同的功能。

结果呢?它运行得非常完美。接着,Nicholas 又要求生成一个围绕 C++ 代码的 Python 包装器。结果这也行得通。

这就是另一个恰好超出 Nicholas 自己完成的烦人任务,但由于他现在可以要求它被自动完成,他得到了一个比原来 Python 代码快 100 倍的结果。

Nicholas 发现自己经常这样做。这里还有一个例子,这次他在 Python 中做了同样的任务。

再次强调,这些任务都不难。但每次 Nicholas 这样做,他都节省了相当多的时间。这是他认为当前 LLM 非常棒的原因之一:它不华丽,也不会因为“这是 Nicholas 用 LLM 让生活更轻松的无聊方式”而获得大量的互联网赞誉,但它却是实实在在的帮助。

For monotonous tasks

有很多事情 Nicholas 需要做,这些事情既无聊,也不需要动脑筋,但必须完成。

实际上,Nicholas 发现自己拖延任务的主要原因之一就是他知道完成这些任务会让人感到烦躁和痛苦。LLMs 大大减少了这种痛苦,使得事情变得更容易开始,因为他知道只需要解决那些有趣的问题。因此,Nicholas 想通过几个非常平凡的例子,来展示他如何通过让 LLMs 帮助他解决问题。

最近,Nicholas 需要反汇编一个用 Python 3.9 编写的 Python 程序。大多数 Python 反汇编器只适用于 Python 3.7 及更早的版本,但无法处理他正在处理的 3.9 二进制文件。

反汇编其实并不难。这主要是一个不犯错误、跟踪 goto 语句来重建控制流的练习。因此,Nicholas 没有花时间手动执行几千个操作码的转换,而是让 LLM 来为他完成这个任务。而且它做得非常好!远比他预期的要好。这里有三次不同的对话,展示了模型如何为他完成这个任务。

另一个例子是当 Nicholas 需要将一些非结构化数据格式化为结构化格式时。例如,他在一个项目中需要获取带有作者姓名的书籍标题列表。所以,他在网上找到了非结构化格式的数据,并让 LLM 帮助他进行格式化。

再比如,最近 Nicholas 正在写一篇关于他如何破解某个防御机制的博客文章,他想展示他所更改代码的完整差异。因此,他将 (1) 差异代码,和 (2) 一个先前的 HTML 化差异示例粘贴进来,并让 LLM 以先前示例的格式生成这个差异。

再举一个例子,作为工作的一部分,Nicholas 经常需要为他使用的资源生成引用。Google Scholar 让引用论文变得很容易,他可以直接复制粘贴正确的引用。但引用网页则稍显麻烦;最近,他已经习惯于让 LLM 为他生成引用。(需要明确的是:他会检查引用是否正确!)

他完全理解,这种任务可能有人会觉得“就这么点事?”但让我们记住,五年前,LLMs 甚至无法连贯地写出一个段落,更不用说为你解决完整的问题了。

To make every user a "power user"

如果你曾经看过某人使用某个工具,而他们的熟练程度远不如你,这可能会让人有点难受。你会看到他们花费几分钟,甚至几个小时在一个任务上,而这个任务其实可以通过某种宏命令或巧妙地使用并行应用程序来自动完成。

但学习这些“咒语”需要时间,而且是具有挑战性的。

例如,最近 Nicholas 试图编写一个 Python 程序来处理 Apple Lisa 键盘的输入。他在网上找到了一些用 C 语言编写的代码,其中包含了很多像 #define KEYNAME key_code 这样的语句。Nicholas 想把这些语句转换成一个 Python 字典,将整数代码映射到相应的字符串。

Nicholas 是个 Emacs 用户,他知道如何在 Emacs 中解决这个问题。这甚至不算太难。以下是他刚刚记录的按键捕获,它将产生这种效果:

C-h C-s #def [回车] M-f [删除] C-d M-f
C-[空格] M-f C-w C-a C-y : " M-f ", C-g C-] } C-[ {

尽管这种操作对 Nicholas 来说几乎是自然的,但他已经花费了半辈子的时间让自己在 Emacs 中足够流畅,以至于这种操作变得自然。但你知道他现在在编辑器中接入 LLM 后会输入什么吗?

C-h C-h rewrite these #defines to a dictionary of {keycode: string, ...}

然后,文本就在他眼前突然被重写了!

在 Nicholas 看来,这类情况表明 LLMs 对非专家的潜在实用性甚至比对专家更高。模型提高了所有人的起点,如果你以前根本无法完成任务,现在你可以做得更多。

As an API reference

真正的程序员会通过阅读参考手册了解工具的工作原理,但 Nicholas 是个懒惰的程序员,他只想直接得到答案,所以他现在会向语言模型提问。

有些人看到这些例子时会说:“LLM 并没有做什么你用现有工具做不到的事情!”他们说得没错,但搜索引擎能做的,实体书也能做到,而实体书能做的,阅读源码也能做到。

但每一种方式都比前一种更简单,而当事情变得更简单时,你会更频繁地去做,并且用不同的方式去做。

因此,Nicholas 现在会直接问模型问题,比如如何获取所有剩余参数,如何在 LaTeX 中将文本变红,或者如何在 LLDB 中找到 GDB 命令的对应命令。这是他经常使用 LLM 的方式之一,因为他在 Emacs 和 shell 中内置了查询 LLM 的工具,大多数时候他都不需要离开编辑器就能得到答案。

To search for things that are hard to find

过去,搜索引擎的使用需要技巧,比如选择合适的关键词和排除不相关的内容。但现在,Nicholas 发现只需直接输入想找的内容,搜索引擎就能找到结果。不过,搜索引擎仍然不是完全的自然语言查询,感觉像在玩反向问答游戏。

语言模型在处理简单任务时更有优势。比如,Nicholas 想知道在 Python 中 "+" 对应的是 __add__,那么 "~" 对应什么,他直接问模型就能得到答案。这种问题用传统搜索引擎很难找到,但语言模型能轻松解答,省去了很多时间。

虽然语言模型还不完美,但它们在不断进步,让 Nicholas 可以更轻松地完成许多他以前可能不会去做的任务,比如写博客时用大写字母开头的“drop cap”效果。总之,语言模型让他的工作变得更加高效。

To solve one-off tasks

有两种类型的程序:一种是需要长期维护的,所以代码要写得干净;另一种是只用一次就丢弃的短期程序。在这种情况下,Nicholas 不在乎代码质量,几乎完全依赖 LLMs 来帮他编写这些一次性程序。

比如,他经常用 LLMs 来生成研究数据的可视化图表,或将数据从一种格式转换为另一种,完成后就删除脚本。他也会让模型帮他写一些简单的脚本,比如将论文读出来检查语法错误,或者下载和处理数据集。

当 Nicholas 遇到需要转换代码或解决一些临时问题时,他也会直接求助 LLMs,而不是自己动手。这种方式既节省时间,又减少了不必要的干扰,让他能专注于更重要的工作。

To explain things to me

Nicholas 最近开始重新接触电子学。虽然他小时候和大学时接触过一些电子知识,但现在做实际项目时,发现有很多小问题让事情变得困难。

虽然他可以读一本实用电子学的书,并可能在某个时候这样做,但他并不想花时间去感觉像是在学习。做电子学的一部分原因是为了从每天的论文工作中解脱出来。

这时,LLMs 很有帮助。虽然它们不像专家那样博学,但它们可以提供大多数问题的答案,让 Nicholas 可以轻松解决问题,而不必费力去搜索互联网。以下是 Nicholas 向语言模型询问电子学基础问题的几个例子:

  • PCB 设计中电阻的“间距”是什么意思?
  • 如何将 0.05 英寸引脚间距的 LoRa 无线电芯片放到 0.1 英寸间距的面包板上?
  • 电容器上的“681”是什么意思?
  • 60mW/sr @ 100mA 在 LED 中是什么意思?
  • 1.44 MB 的软盘是双面的吗?

这些答案虽然不一定完美,但比 Nicholas 完全不知道要好得多。

To solve tasks with known solutions

几乎所有事情都有人做过,而语言模型在提供已有解决方案方面非常出色。

最近,Nicholas 需要提升一些 Python 代码的性能。他让 LLM 将代码重写成 C 语言,并生成接口以便从 Python 调用 C 代码。这些任务并不难,但他不愿意花时间自己去做。现在,Nicholas 习惯了用 LLM 生成更快的代码,甚至会请求生成 Rust 代码以便更容易判断正确性。

同样地,用 multiprocessing 并行化 Python 函数并不难,但编写模板代码麻烦。现在每次需要,Nicholas 都让 LLM 帮忙。他还用 LLM 将 curl 请求转换为更整洁的 Python 代码,以节省时间。

在即将进行的一个项目中,Nicholas 需要知道人们通常用什么作为简单的无线电发射器。由于他想要的是最常见的答案,LLM 是一个完美的选择!

To fix common errors

在 2022 年之前,当 Nicholas 遇到某个流行工具或库的错误信息时,他通常会按以下步骤处理:

  1. 复制错误信息
  2. 粘贴到 Google
  3. 点击顶部的 StackOverflow 链接
  4. 验证问题是否与自己遇到的一致,如果不一致则重复步骤 2
  5. 应用顶部的解决方案
  6. 如果不奏效,再次搜索,修改关键词,祈祷等

说实话,通常出问题的工具离最终要解决的任务相差五个层级,Nicholas 并不关心如何修复它,他只需要它能正常工作。那么在 2024 年,这个流程是这样的:

  1. 复制错误信息
  2. 向 LLM 询问:“如何修复这个错误?[错误信息]”
  3. 按照 LLM 提供的分步解决方案操作
  4. 如果不奏效,就告诉 LLM “这没有用”

Nicholas 没有保存这些交互的记录(或者说他花了一个小时也没找到)。其实,这是有原因的:他已经将这直接集成到自己的工作流程中。

作为一个 Emacs 用户,Nicholas 设置了一个环境:每当程序以非零状态码退出(意味着出错)时,它会自动调用最新、最快的 LLM,请求解释并提供修补方案以直接修复代码中的错误。

如今的模型在大多数情况下还不够好,无法超过 Nicholas 的水平,但已经很接近了。偶尔,LLM 会带来惊喜,修复一些 Nicholas 知道自己可能会很难追踪到的错误,比如某处的拼写错误。

And a million other things

以上提到的对话仅占 Nicholas 在过去一年中与 LLMs 互动总数的不到 2%。Nicholas 预计未来他对这些模型的使用会继续增加。举个例子,2024 年他通过网页界面发起的 LLM 查询比 2023 年增加了 30%,而 API 查询的增长更是难以估计,可能增加了两到三倍。

评价 LLMs 的能力时,应关注它们能做什么,而不是不能做什么。Nicholas 接受过的一个最好的建议是,在面试候选人时,要根据他们能做什么来评价,而不是他们不能做什么。

举个极端的例子,世界上有十亿人说普通话,而 Nicholas 连数到十都不会。如果有人给他一份小学的普通话考试,他肯定会惨败。即使在计算机科学领域,也有他一无所知的领域,比如他对 SQL 的理解仅限于如何写一个有效的 SELECT 语句,除此之外,他一无所知。

因此,当他看到有人在网上争论 LLMs 只是一种炒作,因为“它们连 [X] 都做不到”时,Nicholas 并不理解。[X] 可能是:

  • 统计句子中的单词数量!
  • 写一首每个单词都以字母“A”开头的诗
  • 乘两位数
  • 从列表中随机选择一个元素

因为你上次真正需要做这些事情并认为 LLM 是合适的工具是什么时候?同样地,Nicholas 也不会因为人类无法在脑海中直接除以 64 位整数(这对计算机来说完全是小事)而认为人类毫无用处。构建一个 LLM 无法解决的任务当然容易,但关键是能否找到它们能提供价值的任务。

程序员们已经明白,某些工具适用于不同的用途。想写一个操作系统?也许你应该用 C 而不是 Python。没有人会说“看看 Python 多傻,连强制变量对齐到 32 字节边界都做不到!”这只是抽象层次的问题。语言模型也是如此,它们在非常高的抽象层次上操作,不能指望它们解决连最简单的程序都能解决的任务。但你可以期待它们解决不同类型的任务。

继续滑动看下一个
Renee 创业随笔
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存